#include "main.hh"
#include "pliutil.hh"
#include <stdio.h>
#include <assert.h>
//#include <iostream>
//using namespace std;

extern "C" {
  s_tfcell * core_bootstrap();

  //user's routine
  int hello_task();
  int hello_param_task();
  int show_net_name();
}

// void init();

s_tfcell * core_bootstrap() 
{
  static s_tfcell my_tfs[] =
    {
    /*** Template for an entry:
    { usertask|userfunction, data,
      checktf(), sizetf(), calltf(), misctf(),
      "$tfname", forwref?, Vtool?, ErrMsg? },
    Example:
    { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" },
    ***/

    /*** add user entries here ***/
      {usertask, 0, 0, 0, hello_task, 0, "$hello", 1},
      {usertask, 0, 0, 0, hello_param_task, 0, "$hello_param", 1},

      {usertask, 0, 0, 0, show_net_name, 0, "$show_nets", 1},
  
      {0} /*** final entry must be 0 ***/
    };
  io_printf("PLI tasks & functions register finished !\n");

  //some init
  // init();       //???

  return my_tfs;
}

handle get_signal_hanle(char *netname)
{
  acc_initialize();
  acc_configure(accDisplayErrors, "false");
  //gate = acc_handle_tfarg(1);
  acc_configure(accEnableArgs, "acc_set_scope");
  //acc_set_scope(NULL, SIGNAL_SCOPE);
  acc_set_scope(NULL, "test");				//??
  //handle net = acc_handle_object("test.rst");
  handle net = acc_handle_object(netname);               //what's about this name ? test.rst or just rst ?
  if(!net) {
    acc_set_scope(NULL, NULL);
    net = acc_handle_object(netname);
    if(!net)
      {
        io_printf("not find signal : %s\n", netname);
        tf_dofinish();
      }
  }
  acc_close();
  return net;
}

int get_signal_value(char *netname)
{
  // handle net = acc_handle_object("test.count");
  // s_acc_value v;
  // v.format = accScalarVal;
  // acc_fetch_value(net,"%%", &v);
  // io_printf("%x\n", v.value.scalar);

  //get_signal_hanle(const char *netname)

  // handle hd = get_signal_hanle(netname);
  // s_acc_value v;
  // v.format = accScalarVal;
  // acc_fetch_value(hd,"%%", &v);
  // return v.value.scalar;

  handle net = get_signal_hanle(netname);
  s_acc_value v;
  v.format = accIntVal;
  acc_fetch_value(net,"%%", &v);
  return v.value.integer;

}

int hello_task()
{
  // char *top_mod = get_top_module_name();
  // io_printf("top module is : %s\n", top_mod);

  
  handle net = acc_handle_object("test.count");
  s_acc_value v;
  v.format = accIntVal;
  acc_fetch_value(net,"%%", &v);
  //return v.value.integer;
  io_printf("get value from test.count : %x\n", v.value.integer);

  //io_printf("hello world\n");
  
  // int param = acc_fetch_tfarg_int(1);
  // io_printf("parameter is %d\n", param);
    
  // int val = get_signal_value("test.count");
  // io_printf("val is %x\n", val);
  // return 0;
}
int hello_param_task()
{
  int param = acc_fetch_tfarg_int(1);
  io_printf("get parameter from hello_param() : %d\n", param);
  
  // //int val = get_signal_value("test.count[0]");
  // //int val2 = get_signal_value("test.count[1]");
  // int val = get_signal_value("test.count");
  // io_printf("val is %x\n", val);
  return 0;
}

// int getSingleNetValue()
// {
//   if(!hd) return 0;
//   s_acc_value v;
//   v.format = accScalarVal;
//   acc_fetch_value(hd, "%%", &v);
//   return v.value.Scalar;
// }

int show_net_name()
{
  display_net_name();
}





// $mytask(sigal)
//   handle rxdv = acc_handle_tfarg(1); //the first param
//   io_printf("name : %s\n", acc_fetch_fullname(rxdv));

// typedef struct t_setval_value
// {
//   PLI_INT32 format;
//   union
//     {
//       PLI_BYTE8    *str;
//       PLI_INT32     scalar;
//       PLI_INT32     integer;
//       double        real;
//       p_acc_vecval  vector;
//     } value;
// } s_setval_value, *p_setval_value, s_acc_value, *p_acc_value;

// typedef struct t_setval_delay
// {
//   s_acc_time time;
//   PLI_INT32  model;
// } s_setval_delay, *p_setval_delay;

// typedef struct t_acc_time
// {
//   PLI_INT32 type;
//   PLI_INT32 low,
//             high;
//   double    real;
// } s_acc_time, *p_acc_time;
